// 导入和枚举定义
const { ccclass, property, menu, inspector, executionOrder, disallowMultiple } = cc._decorator;

// 导入PriorityFramework组件
import { TaskScheduler } from '../PriorityFramework/PriorityFramework';

// 导入任务类
import { ShortClickTask, LongClickTask, MultiClickTask, SlideTask } from './task/ButtonTasks';

// 导入事件管理器
import { EventManager } from './manager/EventManager';

// 导入调试管理器
import { DebugManager } from './debug/DebugManager';

// 功能类型枚举
enum FeatureType {
	SHORT = 'short',
	LONG = 'long',
	MULTI = 'multi',
	SLIDE = 'slide'
}

@ccclass
@menu('i18n:MAIN_MENU.component.ui/ButtonPlus')
@inspector('packages://buttonplus/inspector.js')
@executionOrder(-100)
@disallowMultiple
export default class ButtonPlus extends cc.Button {
	// ===== 属性定义 =====
	// 误点相关属性
	@property({ displayName: '误点开关', tooltip: '防止短时间内重复点击。' })
	openMisclick = true;
	@property({ displayName: '误点时间阀值', tooltip: '误点最大时间，建议远小于长按阀值（1秒）、连点间隔时间阀值（0.5秒），特殊情况除外。', min: 0, step: 0.1 })
	misclickTime = 0.2;

	// 短按优先级
	@property({ displayName: '短按优先级', tooltip: '设置短按功能的优先级，值越大优先级越高。', min: 0, step: 1 })
	shortPriority = 1;

	// 长按相关属性
	@property({ displayName: '长按开关', tooltip: '触摸时间大于等于长按时间阀值时，触发长按事件。' })
	openLong = false;
	@property({ displayName: '长按优先级', tooltip: '设置长按功能的优先级，值越大优先级越高。', min: 0, step: 1 })
	longPriority = 3;
	@property({ displayName: '长按时间阀值', tooltip: '触摸时间大于等于此时间时，触发长按事件。\n强烈建议开启长按功能时，远大于误点时间阀值（0.2秒），否则在触摸时间不足误点时间阀值时，会被当成误点处理。', min: 0, step: 0.1 })
	longTime = 1;

	// 连点相关属性
	@property({ displayName: '连点开关', tooltip: '两次触摸结束时间间隔小于等于连点间隔时间阀值时，连点次数增加。连点次数等于连点次数阀值时，触发连点事件。' })
	openMulti = false;
	@property({ displayName: '连点优先级', tooltip: '设置连点功能的优先级，值越大优先级越高。', min: 0, step: 1 })
	multiPriority = 2;
	@property({ displayName: '连点次数阀值', tooltip: '连点最小次数，连点次数等于此次数时，触发连点事件。', min: 2, step: 1 })
	multiCount = 2;
	@property({ displayName: '连点间隔时间阀值', tooltip: '连点最大间隔时间，两次触摸结束时间间隔大于此时间将重置连点计数。\n强烈建议开启连点功能时，关闭误点开关或设置较小的误点时间阀值，否则在触摸时间不足误点时间阀值时，会被当成误点处理。', min: 0, step: 0.1 })
	multiInterval = 0.5;

	// 滑动相关属性
	@property({ displayName: '滑动开关', tooltip: '滑动距离大于等于滑动距离阀值时，触发滑动事件。' })
	openSlide = false;
	@property({ displayName: '滑动优先级', tooltip: '设置滑动功能的优先级，值越大优先级越高。', min: 0, step: 1 })
	slidePriority = 3;
	@property({ displayName: '滑动距离阀值', tooltip: '滑动最小距离，滑动距离大于等于此距离触发滑动事件。\n强烈建议开启滑动功能时，关闭误点开关或设置较小的误点时间阀值，否则在触摸时间不足误点时间阀值时，会被当成误点处理。', min: 0, step: 1 })
	slideDistance = 20;

	// 触摸取消相关属性
	@property({ displayName: '触摸取消开关', tooltip: '开启后，触摸取消时，会触发取消事件。否则，触发触摸结束事件。' })
	openCancel = true;

	// 调试相关属性
	@property({ tooltip: '是否启用调试日志' })
	openDebug: boolean = false;

	// ===== 状态管理对象 =====
	private _state = {
		// 误点状态
		misclickFlag: false,

		// 长按状态
		longFlag: false,

		// 连点状态
		clickCount: 0,
		lastClickTime: 0,

		// 滑动状态
		startPos: cc.Vec2.ZERO.clone(),
		endPos: cc.Vec2.ZERO.clone(),
		isSliding: false,
		currentSlideDistance: 0,
		// 滑动检测相关
		lastDistance: 0,
		lastMoveTime: 0,
		lastSlideTime: 0,
		// 新增：滑动方向稳定性检测
		lastDirections: [] as string[],
		directionStability: 0,
		// 新增：触摸事件节流控制
		touchThrottle: false
	};

	// 滑动节流时间(ms)
	private _slideThrottleTime: number = 50;

	// 缓存方法(与cc.Button的_updateState方法保持一致)
	private _updateStateMethod: Function = null;

	// PriorityFramework 任务调度器
	private _taskScheduler: TaskScheduler = null;

	// 事件缓存
	private _currentEvent: cc.Event.EventTouch = null;

	// 事件管理器
	private _eventManager: EventManager = null;

	// 调试管理器
	private _debugManager: DebugManager = null;

	// ===== 生命周期方法 =====
	protected onLoad(): void {
		try {
			// 安全调用父类onLoad
			if (super.onLoad) {
				super.onLoad();
			}
			// 缓存_updateState方法
			this._updateStateMethod = this['_updateState'];
			// 初始化状态对象
			this._resetAllState();
			// 初始化PriorityFramework任务调度器
			this._taskScheduler = new TaskScheduler();
			// 初始化事件管理器
			this._eventManager = new EventManager(this.node);
			// 初始化调试管理器
			this._debugManager = new DebugManager(this);
		} catch (error) {
			this._log(`Failed to call parent onLoad: ${error}`);
		}
	}

	protected onDestroy(): void {
		// 清理所有定时器
		this.unscheduleAllCallbacks();

		// 清理所有可能的事件监听器
		this.node.targetOff(this);
		this.removeAllEvents();

		// 清理调试标签
		if (this._debugManager) {
			this._debugManager.destroyLabel();
			this._debugManager = null;
		}

		// 清理引用，防止内存泄漏
		this._updateStateMethod = null;

		// 清理任务调度器
		if (this._taskScheduler) {
			this._taskScheduler.cancelAllTasks();
			this._taskScheduler = null;
		}

		// 清理事件管理器
		if (this._eventManager) {
			this._eventManager = null;
		}

		// 清理事件缓存
		this._currentEvent = null;

		// 深度清理状态对象中的引用
		if (this._state) {
			this._state.startPos = null;
			this._state.endPos = null;
			this._state.lastDirections = null;
			// 将_state对象置为null，彻底清理
			this._state = null as any;
		}

		try {
			if (super.onDestroy) {
				super.onDestroy();
			}
		} catch (error) {
			// 静默处理，避免在销毁过程中出错
		}
	}

	protected onEnable(): void {
		try {
			// 安全调用父类onEnable
			if (super.onEnable) {
				super.onEnable();
			}
		} catch (error) {
			this._log(`Failed to call parent onEnable: ${error}`);
		}

		// 重置所有状态
		this._resetAllState();

		// 确保定时器被清理
		this.unscheduleAllCallbacks();
	}

	protected onDisable(): void {
		// 确保所有定时器都被清理
		this.unscheduleAllCallbacks();

		// 重置所有状态
		this._resetAllState();

		// 注意：这里不需要手动移除事件监听，因为onEnable中没有添加固定的监听器
		// 动态添加的监听器应该由调用方负责移除
		try {
			// 安全调用父类onDisable
			if (super.onDisable) {
				super.onDisable();
			}
		} catch (error) {
			this._log(`Failed to call parent onDisable: ${error}`);
		}
	}

	/** 重写 */
	// ===== 触摸事件处理 =====
	_onTouchBegan(event: cc.Event.EventTouch): void {
		if (!this.interactable || !this.enabledInHierarchy || !this._isValidComponent()) return;

		// 记录触摸开始时间（用于调试）
		if (this._debugManager) {
			this._debugManager.resetDebugInfo();
			this._debugManager.getDebugInfo().touchStart = Date.now();
		}

		// 重置触摸状态
		this._resetTouchState();
		this._state.startPos.set(event.getLocation());
		this._state.endPos.set(event.getLocation());

		// 开启长按功能时，设置长按开始定时器。等待到长按时间阀值后，触发长按开始事件。
		if (this.openLong) {
			this._setScheduleLongStart();
		}

		this._updateButtonState(true);
		event.stopPropagation();
	}
	_onTouchEnded(event: cc.Event.EventTouch): void {
		if (!this.interactable || !this.enabledInHierarchy || !this._isValidComponent()) return;

		// 记录触摸结束时间（用于调试）
		if (this._debugManager) {
			this._debugManager.getDebugInfo().touchEnd = Date.now();
		}

		this.unscheduleAllCallbacks();

		// 记录触摸结束位置和时间
		this._state.endPos.set(event.getLocation());

		// 长按结束处理
		this._handleLongClickEnd(event);

		// 保存当前滑动状态，因为需要在事件处理中使用
		const wasSliding = this._state.isSliding;
		const slideDistance = this._state.currentSlideDistance;

		// 非滑动且非误点状态处理
		if (this['_pressed'] && !this._state.isSliding && !this._state.misclickFlag) {
			// 增加点击计数
			this._state.clickCount++;
			this._handleNormalClick(event);
		} else if (wasSliding) {
			// 如果是滑动结束，也需要进入优先级系统处理
			this._handleNormalClick(event);
		}

		// 所有事件处理完成后再重置滑动状态
		this._state.isSliding = false;
		this._state.currentSlideDistance = 0;
		this._updateButtonState(false);
		event.stopPropagation();
	}
	_onTouchCancel(event?: cc.Event.EventTouch): void {
		// 如果未开启取消功能，则调用触摸结束处理
		if (!this.openCancel) {
			// 创建一个模拟的触摸事件对象，传递给_onTouchEnded
			const mockEvent = event || {
				getLocation: () => this._state.endPos,
				stopPropagation: () => { }
			} as any;
			this._onTouchEnded(mockEvent);
			return;
		}

		if (!this.interactable || !this.enabledInHierarchy || !this._isValidComponent()) return;

		// 记录触摸取消时间（用于调试）
		if (this._debugManager) {
			this._debugManager.getDebugInfo().touchCancel = Date.now();
		}

		this.unscheduleAllCallbacks();

		// 重置触摸状态并更新按钮状态
		this._resetTouchState();
		this._updateButtonState(false);
	}

	_onTouchMove(event: cc.Event.EventTouch): void {
		if (!this.interactable || !this.enabledInHierarchy || !this['_pressed'] || !this._isValidComponent()) return;

		// 仅在开启滑动功能时处理
		if (this.openSlide) {
			// 更新结束位置
			this._state.endPos.set(event.getLocation());

			// 计算滑动距离
			const distance = this._state.startPos.sub(this._state.endPos).mag();
			this._state.currentSlideDistance = distance;

			// 处理滑动检测
			this._processSlideDetection(event, distance);
		}
	}

	/**
	 * 处理滑动检测（优化版，整合节流控制）
	 */
	private _processSlideDetection(event: cc.Event.EventTouch, distance: number): void {
		const currentTime = Date.now();

		// 如果误点开关开启且处于误点保护期，标记可能被拦截
		let adjustedDistance = distance;
		let wasMisclickIntercepted = false;

		if (this.openMisclick && this._state.misclickFlag) {
			// 计算动态阈值
			const adjustedThreshold = this._calculateDynamicThreshold(currentTime, distance);
			// 检查理论上是否应该触发滑动事件
			if (distance >= adjustedThreshold && !this._state.isSliding) {
				wasMisclickIntercepted = true;
				// 误点保护期间，保持原始距离，但在优先级系统中会考虑这个状态
			}
		}

		// 在本应触发滑动但被误点拦截的情况下输出警告
		if (wasMisclickIntercepted) {
			this._log(`警告：当前滑动本应触发滑动事件，但由于误点保护期，滑动事件被拦截`);
		}

		// 计算滑动速度，用于动态调整阈值
		let adjustedThreshold = this._calculateDynamicThreshold(currentTime, distance);

		// 首次触发滑动（使用调整后的距离）
		if (adjustedDistance >= adjustedThreshold && !this._state.isSliding) {
			this._triggerSlideStart(event, adjustedDistance);
			return; // 首次触发后直接返回，避免重复处理
		}

		// 持续滑动处理（添加频率控制）
		if (this._state.isSliding && currentTime - this._state.lastSlideTime > this._slideThrottleTime) {
			// 检查滑动方向
			this._checkSlideDirectionEnhanced(event);

			// 触发持续滑动事件
			const slidingData = { target: this, event: event, distance: distance, direction: this._getMainDirection() };
			this.node.emit('sliding', slidingData);
			this._logEvent('sliding', slidingData);
			this._state.lastSlideTime = currentTime;
		}

		// 更新历史数据
		this._state.lastDistance = distance;
		this._state.lastMoveTime = currentTime;
	}

	/**
	 * 计算动态滑动阈值
	 */
	private _calculateDynamicThreshold(currentTime: number, distance: number): number {
		let adjustedThreshold = this.slideDistance;

		// 根据滑动速度调整阈值
		if (this._state.lastMoveTime > 0 && this._state.lastDistance > 0) {
			const distanceDelta = distance - this._state.lastDistance;
			const timeDelta = (currentTime - this._state.lastMoveTime) / 1000;
			const speed = Math.abs(distanceDelta / timeDelta);

			// 快速滑动时降低阈值，慢速滑动时提高阈值
			adjustedThreshold = this.slideDistance * (
				speed > 500 ? 0.6 :
					speed > 300 ? 0.7 :
						speed > 100 ? 0.9 : 1.0
			);
		}

		// 确保阈值在合理范围内
		return Math.max(5, adjustedThreshold);
	}

	/**
	 * 触发滑动开始事件
	 */
	private _triggerSlideStart(event: cc.Event.EventTouch, distance: number): void {
		this._state.isSliding = true;
		const slideStartData = { target: this, event: event, distance: distance };
		this.node.emit('slidestart', slideStartData);
		this._logEvent('slidestart', slideStartData);
		// 滑动开始事件立即触发，但滑动结束事件将在优先级系统中处理
		this.unscheduleAllCallbacks();
	}

	// ===== 功能辅助方法 =====
	private _resetTouchState(): void {
		// 重置误点状态
		this._state.misclickFlag = false;

		this._state.isSliding = false;
		this._state.longFlag = false;
		this._state.currentSlideDistance = 0;
		// 重置滑动检测相关状态
		this._state.lastDistance = 0;
		this._state.lastMoveTime = 0;
		this._state.lastSlideTime = 0;
		this._state.lastDirections = [];
		this._state.directionStability = 0;
		this.unscheduleAllCallbacks();
	}

	/**
	 * 重置所有状态（完善版）
	 */
	private _resetAllState(): void {
		// 重置所有状态变量，确保完全干净的状态
		this._state = {
			// 重置误点状态
			misclickFlag: false,

			// 重置长按状态
			longFlag: false,

			// 重置连点状态
			clickCount: 0,
			lastClickTime: 0,

			// 滑动状态
			startPos: this._state.startPos || cc.Vec2.ZERO.clone(),
			endPos: this._state.endPos || cc.Vec2.ZERO.clone(),
			isSliding: false,
			currentSlideDistance: 0,
			// 滑动检测相关
			lastDistance: 0,
			lastMoveTime: 0,
			lastSlideTime: 0,
			// 滑动方向稳定性检测
			lastDirections: [],
			directionStability: 0,
			// 触摸事件节流控制
			touchThrottle: false
		};

		// 重置调试信息
		if (this._debugManager) {
			this._debugManager.resetDebugInfo();
		}
	}

	/**
	 * 调试日志输出
	 */
	private _log(message: string): void {
		if (this._debugManager) {
			this._debugManager.log(message);
		}
	}

	/**
	 * 事件日志输出
	 */
	private _logEvent(eventName: string, details?: any): void {
		if (this._debugManager) {
			this._debugManager.logEvent(eventName, details);
		}
	}

	/**
	 * 设置长按开始定时器。等待到长按时间阀值后，触发长按开始事件。
	 */
	private _setScheduleLongStart(): void {
		this.scheduleOnce(() => {
			if (!this._isValidComponent()) return;

			// 已按下时，触发长按开始事件
			if (this['_pressed']) {
				const longStartData = { target: this };
				this.node.emit('longstart', longStartData);
				this._logEvent('longstart', longStartData);
				this._state.longFlag = true;
			}
		}, this.longTime);
	}

	/**
	 * 处理长按结束
	 */
	private _handleLongClickEnd(event: cc.Event.EventTouch): void {
		if (!this._isValidComponent()) return;
		// 长按事件已移至LongClickTask.execute中处理
	}

	/**
	 * 处理正常点击事件
	 */
	private _handleNormalClick(event: cc.Event.EventTouch): void {
		this._log('处理正常点击');

		if (!this._isValidComponent()) {
			return;
		}

		// 使用简化的优先级处理机制
		this._handleEventByPriority(event);

		// 误点处理（现在支持连点模式和滑动）
		if (this.openMisclick) {
			// 检查长按时间与误点时间的关系
			const currentTime = Date.now();
        const debugInfo = this._debugManager.getDebugInfo();
        const pressDuration = (currentTime - debugInfo.touchStart) / 1000;

			// 如果是长按且长按时间大于长按阈值但小于误点时间，输出警告
			if (this.openLong && pressDuration >= this.longTime && pressDuration < this.misclickTime) {
				this._log(`警告：长按时间(${pressDuration.toFixed(2)}s)大于长按阈值(${this.longTime}s)但小于误点时间(${this.misclickTime}s)`);
			}

			this._state.misclickFlag = true;

			this.scheduleOnce(() => {
				if (this._isValidComponent()) {
					this._state.misclickFlag = false;
				}
			}, this.misclickTime);
		}
	}

	/**
	 * 按优先级处理事件（使用PriorityFramework）
	 */
	private _handleEventByPriority(event: cc.Event.EventTouch): void {
		// 清除之前的所有任务
		this._taskScheduler.cancelAllTasks();

		// 缓存当前事件
		this._currentEvent = event;

		// 考虑误点保护状态
		if (!(this.openMisclick && this._state.misclickFlag)) {
			// 检查滑动功能
			if (this.openSlide && this._state.isSliding) {
				this._taskScheduler.addTask(new SlideTask(this, event, this.slidePriority));
			}

			// 检查长按功能
			if (this.openLong && this._state.longFlag) {
				this._taskScheduler.addTask(new LongClickTask(this, event, this.longPriority));
			}

			// 检查连点功能 
			if (this.openMulti && this._state.clickCount === this.multiCount) {
				this._taskScheduler.addTask(new MultiClickTask(this, event, this.multiPriority));
			}

			// 检查短按功能
			this._taskScheduler.addTask(new ShortClickTask(this, event, this.shortPriority));
		}

		// 执行最高优先级的任务
		if (this._taskScheduler.getTaskCount() > 0) {
			this._taskScheduler.executeNext();
		}
	}

	// 事件处理逻辑已统一移至Task类的execute方法中处理

	/**
	 * 检查组件有效性
	 */
	private _isValidComponent(): boolean {
		if (!this.node || !this.node.isValid || !this.enabled) {
			return false;
		}
		return true;
	}

	/**
	 * 更新按钮状态
	 */
	private _updateButtonState(pressed: boolean): void {
		// 先检查组件有效性
		if (!this._isValidComponent()) return;

		try {
			// 仅设置状态，避免访问可能不存在的方法
			if (this && typeof this === 'object') {
				this['_pressed'] = pressed;
				// 使用缓存的方法
				if (typeof this._updateStateMethod === 'function') {
					this._updateStateMethod.call(this);
				}
			}
		} catch (error) {
			// 静默处理错误，确保不会阻止其他功能
			this._log(`更新按钮状态失败: ${error}`);
		}
	}

	// 连点事件处理逻辑已移至MultiClickTask.execute中处理

	/**
	 * 重置点击计数
	 */
	private _resetClickCount = () => {
		if (!this._isValidComponent()) return;
		this._state.clickCount = 0;
	}

	/**
	 * 检查滑动方向并触发相应事件（优化版，更简洁高效）
	 */
	private _checkSlideDirectionEnhanced(event: cc.Event.EventTouch): void {
		if (!this._isValidComponent()) return;

		// 计算滑动向量
		const dx = this._state.endPos.x - this._state.startPos.x;
		const dy = this._state.endPos.y - this._state.startPos.y;
		const absDx = Math.abs(dx);
		const absDy = Math.abs(dy);

		// 只有实际滑动时才处理
		if (absDx < 5 && absDy < 5) return; // 微小移动忽略

		// 确定方向和事件名称
		const { eventName, direction } = this._determineSlideDirection(dx, dy, absDx, absDy);

		// 检查方向稳定性
		if (this._isDirectionStable(direction)) {
			// 触发事件前检查误点状态
			if (this.openMisclick && this._state.misclickFlag) {
				this._log(`警告：当前滑动在误点保护期内，但启用了滑动模式，可能导致滑动事件被拦截`);
			}

			// 触发事件
			const eventData = { target: this, event: event, dx: dx, dy: dy, distance: this._state.currentSlideDistance };
			this.node.emit(eventName, eventData);
			this._logEvent(eventName, eventData);
		}
	}

	/**
	 * 确定滑动方向和对应的事件名称
	 */
	private _determineSlideDirection(dx: number, dy: number, absDx: number, absDy: number): { eventName: string, direction: string } {
		// 轴向滑动检测
		const thresholdRatio = 1.2; // 降低阈值比例，提高灵敏度

		if (absDx >= absDy * thresholdRatio) {
			// 水平滑动
			return {
				eventName: dx > 0 ? 'slideright' : 'slideleft',
				direction: dx > 0 ? 'right' : 'left'
			};
		} else if (absDy >= absDx * thresholdRatio) {
			// 垂直滑动
			return {
				eventName: dy > 0 ? 'slideup' : 'slidedown',
				direction: dy > 0 ? 'up' : 'down'
			};
		} else {
			// 对角线滑动 - 使用角度判断
			return this._determineDiagonalDirection(dx, dy);
		}
	}

	/**
	 * 确定对角线滑动方向
	 */
	private _determineDiagonalDirection(dx: number, dy: number): { eventName: string, direction: string } {
		const angle = Math.atan2(dy, dx) * 180 / Math.PI;

		// 根据角度范围确定主方向
		if ((angle >= -22.5 && angle < 22.5) ||
			(angle >= 157.5 && angle <= 180) ||
			(angle >= -180 && angle < -157.5)) {
			return { eventName: 'slideright', direction: 'right' };
		} else if (angle >= 67.5 && angle < 112.5) {
			return { eventName: 'slideup', direction: 'up' };
		} else if (angle >= -157.5 && angle < -112.5) {
			return { eventName: 'slidedown', direction: 'down' };
		} else {
			return { eventName: 'slideleft', direction: 'left' };
		}
	}

	/**
	 * 检查方向是否稳定（优化：增加快速滑动特殊处理）
	 */
	private _isDirectionStable(currentDirection: string): boolean {
		const maxHistory = 3;
		let stabilityThreshold = 2;

		// 优化：根据滑动速度动态调整稳定性阈值
		const currentTime = Date.now();
		if (this._state.lastMoveTime > 0) {
			const timeDelta = currentTime - this._state.lastMoveTime;
			if (timeDelta > 0) {
				const speed = this._state.currentSlideDistance / timeDelta * 1000; // 像素/秒
				// 快速滑动时降低稳定性要求
				stabilityThreshold = speed > 800 ? 1 : stabilityThreshold;
			}
		}

		// 更新方向历史
		this._state.lastDirections.push(currentDirection);
		if (this._state.lastDirections.length > maxHistory) {
			this._state.lastDirections.shift();
		}

		// 检查方向稳定性
		if (this._state.lastDirections.length > 1) {
			const lastDirection = this._state.lastDirections[this._state.lastDirections.length - 2];
			if (currentDirection === lastDirection) {
				this._state.directionStability++;
			} else {
				this._state.directionStability = 1; // 重置但保留当前方向计数
			}
		} else {
			this._state.directionStability = 1; // 首次方向
		}

		// 只有方向稳定或首次检测时才触发事件
		return this._state.directionStability >= stabilityThreshold ||
			this._state.lastDirections.length === 1;
	}

	/**
	 * 获取主要滑动方向
	 * @returns 主要滑动方向 'up', 'down', 'left', 'right', 'none'
	 */
	private _getMainDirection(): string {
		const dx = this._state.endPos.x - this._state.startPos.x;
		const dy = this._state.endPos.y - this._state.startPos.y;
		const absDx = Math.abs(dx);
		const absDy = Math.abs(dy);

		if (absDx > absDy) {
			return dx > 0 ? 'right' : 'left';
		} else if (absDy > absDx) {
			return dy > 0 ? 'up' : 'down';
		}
		return 'none';
	}

	// ===== 事件绑定API =====

	/**
	 * 添加短按事件
	 * @param callback 点击回调
	 * @param target 目标
	 */
	public addClick(callback: Function, target: Object): void {
		if (!this._eventManager.bindEvent('shortclick', callback, target)) {
			this._log('addClick: 参数无效');
		}
	}

	/**
	 * 添加长按事件
	 * @param startFunc 开始回调
	 * @param endFunc 结束回调
	 * @param target 目标
	 */
	public addLong(startFunc: Function, endFunc: Function, target: Object): void {
		if (!target) {
			this._log('addLong: 目标参数无效');
			return;
		}

		if (startFunc) {
			this._eventManager.bindEvent('longstart', startFunc, target);
		}
		if (endFunc) {
			this._eventManager.bindEvent('longend', endFunc, target);
		}
	}

	/**
	 * 添加连点事件
	 * @param callback 回调函数
	 * @param target 目标
	 */
	public addMulti(callback: Function, target: Object): void {
		if (!this._eventManager.bindEvent('multi', callback, target)) {
			this._log('addMulti: 参数无效');
		}
	}

	/**
	 * 添加滑动事件
	 * @param direction 滑动方向: 'up', 'down', 'left', 'right', 'start', 'ing'
	 * @param callback 回调函数
	 * @param target 目标
	 */
	public addSlideEvent(direction: string, callback: Function, target: Object): void {
		if (typeof callback !== 'function' || !target || !direction) {
			this._log('addSlideEvent: 参数无效');
			return;
		}

		const eventName = this._eventManager.getEventName(direction);
		if (eventName) {
			this._eventManager.bindEvent(eventName, callback, target);
		} else {
			this._log(`addSlideEvent: 未知方向 ${direction}`);
		}
	}

	/**
	 * 移除事件监听器
	 * @param eventName 事件名称
	 * @param callback 回调函数
	 * @param target 目标
	 */
	public removeEvent(eventName: string, callback: Function, target: Object): void {
		if (eventName && callback && target) {
			this.node.off(eventName, callback, target);
			this._log(`已移除事件监听: ${eventName}`);
		}
	}

	/**
	 * 移除所有事件监听器
	 */
	public removeAllEvents(): void {
		// 移除所有自定义事件监听器
		const events = ['shortclick', 'longstart', 'longend', 'multi', 'slideup', 'slidedown', 'slideleft', 'slideright', 'slidestart', 'sliding'];
		events.forEach(event => {
			this.node.off(event);
		});
		this._log('已移除所有事件监听器');
	}
}
